package com.System.LearnSystemBasic;
import com.System.LearnSystem.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


class longin{//用于临时储存客户端发来的请求信息（用户名和密码）
	private String username;
	private String password;
	
	public longin(){
		
	}
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

class DatabaseException extends RuntimeException {

	public DatabaseException(String message) {
        super(message);
    }
    public DatabaseException(String message, Throwable cause) {
        super(message, cause);
    }
}


@WebServlet("/Login")
public class Login extends HttpServlet
{	

	
	public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException
	{
		
		StringBuilder json = new StringBuilder();//读取json请求
        BufferedReader reader = req.getReader();
        String line;
        while ((line = reader.readLine()) != null) {
            json.append(line);
        }
        String jsonStr = json.toString();
       
        
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());//注册驱动保证序列化
        longin loin = objectMapper.readValue(jsonStr, longin.class);
		res.setContentType("application/json;charset=UTF-8");//设置响应格式 
	    PrintWriter out = res.getWriter();
	   
	    
	    if(LoginAPI(loin.getUsername(),loin.getPassword()))//查询数据库的信息，确认响应结果
		{   	
			User user = settingUser(loin.getUsername(),loin.getPassword());			
			if(user.getStatus()==0)
			{	if("TEACHER".equals(user.getRole()))//根据角色的不同设置不同的响应
				{
					Teacher tea = settingTeacher(user,loin.getUsername());
					Token<Teacher> tk = new Token<Teacher>(tea,tea.getUsername(),"TEACHER");//发配令牌
					Result<Token<Teacher>> resulttea = Result.success(tk);
					resulttea.setMessage("登录成功");
					out.println(objectMapper.writeValueAsString(resulttea));
				}
				else if("STUDENT".equals(user.getRole()))
				{
					Student st = settingStudent(user,loin.getUsername());
					Token<Student> tk = new Token<Student>(st,st.getUsername(),"STUDENT");//发配令牌
					Result<Token<Student>> resultst = Result.success(tk);
					resultst.setMessage("登录成功");
					out.println(objectMapper.writeValueAsString(resultst));
				}
				else
				{
					Token<User> tk = new Token<User>(user,user.getUsername(),"ADMIN");
					Result<Token<User>> resultuser = Result.success(tk);
					resultuser.setMessage("登录成功");
					out.println(objectMapper.writeValueAsString(resultuser));
					//System.out.println(tk.getUsernameFromToken());
				}
			}
			else if(user.getStatus()==1)
			{
				Result<Object> result = Result.error(403,"该用户禁止访问");	
				out.println(objectMapper.writeValueAsString(result));
			}
			else
			{
				Result<Object> result = Result.error(401,"该用户状态异常");	
				out.println(objectMapper.writeValueAsString(result));
			}
		}
		else
		{
			Result<Object> result = Result.error(400,"用户或密码错误");	
			out.println(objectMapper.writeValueAsString(result));
		}
	}
	
 
    public static boolean LoginAPI(String username, String password)//具体的登录
    {
    	String sql = "SELECT * FROM t_user where username =? AND password =?";//检索信息的sql语句，用于比对用户输入的信息
    	try (Connection conn = sqlConnection.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) 
    	{
    		pstmt.setString(1, username);//将对应信息替换？的位置
    		pstmt.setString(2, password);
    		ResultSet rs = pstmt.executeQuery();
    		return rs.next();//返回数据库的比对结果
		} catch (SQLException e) {
			throw new DatabaseException("登录验证时数据库操作失败", e);
		}
    }

    public static User settingUser(String username, String password)//实例化用户信息
    {
    	User user = new User();
    	String sql = "SELECT * FROM t_user where username =? AND password =?";//检索信息的sql语句，用于比对用户输入的信息
    	try (Connection conn = sqlConnection.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) 
	{
    		pstmt.setString(1, username);//将对应信息替换？的位置
    		pstmt.setString(2, password);
    		ResultSet rs = pstmt.executeQuery();
    		while(rs.next())//将信息存入对应成员
    		{
    			user.setId((long)rs.getInt("id"));
    			user.setRole(rs.getString("role"));
    			user.setCreateTime(rs.getTimestamp("create_time"));
    			user.setCreateTime(rs.getTimestamp("update_time"));
    			user.setPassword(password);
    			user.setUsername(username);
    			if(rs.getInt("status")==1)
    			{
    				user.setStatus(1);
    			}
    			else
    			{
    				user.setStatus(0);
    			}			
    		}
		} catch (SQLException e) {
			throw new DatabaseException("登录验证时数据库操作失败", e);
		}
    	return user;
    }
    
    public static teacher settingTeacher(User user,String username)//实例化教师信息
    {
    	teacher tea = new teacher(user);
    	String sql = "SELECT * FROM t_teacher where username =?;";//检索信息的sql语句，用于比对用户输入的信息
    	try (Connection conn = sqlConnection.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) 
	{
    		pstmt.setString(1, username);//将对应信息替换？的位置  		
    		ResultSet rs = pstmt.executeQuery();
    		while(rs.next())//将信息存入对应成员
    		{
    			tea.setDepartmentId(rs.getLong("department_id"));
    			tea.setCreateTime(rs.getTimestamp("create_time"));
    			tea.setCreateTime(rs.getTimestamp("update_time"));
    			tea.setTeacherNo(rs.getString("teacher_no"));
    			tea.setName(rs.getString("name"));
    		}
		} catch (SQLException e) {
			throw new DatabaseException("登录验证时数据库操作失败", e);
		}
    	return tea;
    }
    
    public static student settingStudent(User user,String username)//实例化学生信息
    {
    	student st = new student(user);
    	String sql = "SELECT * FROM t_student where username =?;";//检索信息的sql语句，用于比对用户输入的信息
    	try (Connection conn = sqlConnection.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) 
	{
    		pstmt.setString(1, username);//将对应信息替换？的位置  		
    		ResultSet rs = pstmt.executeQuery();
    		while(rs.next())//将信息存入对应成员
    		{
    			st.setDepartmentId(rs.getLong("department_id"));
    			st.setCreateTime(rs.getTimestamp("create_time"));
    			st.setCreateTime(rs.getTimestamp("update_time"));
    			st.setStudentNo(rs.getString("student_no"));
    			st.setName(rs.getString("name"));
    		}
		} catch (SQLException e) {
			throw new DatabaseException("登录验证时数据库操作失败", e);
		}
    	return st;
    }
    
}

class teacher extends Teacher//覆写不需要序列化的方法
{
	@JsonIgnore
	public Long getDepartmentId() {
		return departmentId;
	}
	@JsonIgnore
	public String getPhone() {
		return phone;
	}
	@JsonIgnore
	public String getEmail() {
		return email;
	}
	public teacher(User user)
	{
		super(user);
	}
}

class student extends Student
{
	@JsonIgnore
	public Long getDepartmentId() {
		return departmentId;
	}
	@JsonIgnore
	public String getPhone() {
		return phone;
	}
	@JsonIgnore
	public String getEmail() {
		return email;
	}
	public student(User user)
	{
		super(user);
	}
}



